package container;

import annotations.Configuration;
import annotations.Bean;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class SimpleIOCContainer {
    private Map<String, Object> beans = new HashMap<>();

    public SimpleIOCContainer() {
        System.out.println("Simple IOC Container initialized");
    }

    public void register(Class<?> configClass) {
        System.out.println("Registering configuration: " + configClass.getName());

        // 检查是否是配置类
        if (!configClass.isAnnotationPresent(Configuration.class)) {
            throw new RuntimeException("Class must be annotated with @Configuration: " + configClass.getName());
        }

        try {
            // 创建配置类实例
            Object configInstance = configClass.getDeclaredConstructor().newInstance();

            // 扫描所有带有@Bean注解的方法
            for (Method method : configClass.getDeclaredMethods()) {
                if (method.isAnnotationPresent(Bean.class)) {
                    // 获取bean名称
                    Bean beanAnnotation = method.getAnnotation(Bean.class);
                    String beanName = beanAnnotation.name().isEmpty()
                            ? method.getName()
                            : beanAnnotation.name();

                    System.out.println("Creating bean: " + beanName);

                    // 确保方法可访问
                    method.setAccessible(true);

                    // 调用方法获取bean实例
                    Object bean = method.invoke(configInstance);

                    // 将bean存入容器
                    beans.put(beanName, bean);

                    System.out.println("Bean created and registered: " + beanName + " -> " + bean.getClass().getSimpleName());
                }
            }

            System.out.println("Configuration registration completed successfully");

        } catch (Exception e) {
            throw new RuntimeException("Failed to register configuration: " + configClass.getName(), e);
        }
    }

    public Object getBean(String name) {
        Object bean = beans.get(name);
        if (bean == null) {
            throw new RuntimeException("Bean not found: " + name);
        }
        return bean;
    }

    public <T> T getBean(String name, Class<T> type) {
        Object bean = beans.get(name);
        if (bean == null) {
            throw new RuntimeException("Bean not found: " + name);
        }
        if (!type.isInstance(bean)) {
            throw new RuntimeException("Bean '" + name + "' is not of type: " + type.getName() +
                    ", actual type: " + bean.getClass().getName());
        }
        return type.cast(bean);
    }

    public boolean containsBean(String name) {
        return beans.containsKey(name);
    }

    public int getBeanCount() {
        return beans.size();
    }

    public void listAllBeans() {
        System.out.println("\n=== All Registered Beans ===");
        beans.forEach((name, bean) -> {
            System.out.println(name + " -> " + bean.getClass().getName());
        });
        System.out.println("Total beans: " + beans.size());
    }
}